#ifndef WPML_H
#define WPML_H

#include <string>
#include <vector>
#include <chrono>
#include "Buffer.h"

#ifdef _WIN32
    #ifdef BUILDING_DLL
        #define WPML_API __declspec(dllexport)
    #else
        #define WPML_API __declspec(dllimport)
    #endif
#else
    #define WPML_API __attribute__((visibility("default")))
#endif

// 定义命名空间以匹配KML中的wpml前缀
namespace wpml {
    // 枚举类型定义
    enum FlyToWaylineMode {
        Safely,
        PointToPoint
    };

    enum FinishAction {
        GoHome,
        NoAction,
        AutoLand,
        GotoFirstWaypoint
    };

    enum ExitOnRCLost {
        GoContinue,
        ExecuteLostAction
    };

    enum ExecuteRCLostAction {
        GoBack,
        Landing,
        Hover
    };

    enum TemplateType {
        Waypoint,
        Mapping2d,
        Mapping3d,
        MappingStrip
    };

    enum CoordinateMode {
        WGS84
    };

    enum HeightMode {
        EGM96,
        RelativeToStartPoint,
        AboveGroundLevel,
        RealTimeFollowSurface
    };

    enum PositioningType {
        GPS,
        RTKBaseStation,
        QianXun,
        Custom
    };

    enum GimbalPitchMode {
        Manual,
        UsePointSetting
    };

    enum WaypointTurnMode {
        CoordinateTurn,
        ToPointAndStopWithDiscontinuityCurvature,
        ToPointAndStopWithContinuityCurvature,
        ToPointAndPassWithContinuityCurvature
    };

    enum WaypointHeadingMode {
        Fixed,
        FollowWayline
    };

    // 结构体定义
    struct DroneInfo {
        int droneEnumValue;
        int droneSubEnumValue;
        
        DroneInfo() : droneEnumValue(67), droneSubEnumValue(0) {}
    };

    struct PayloadInfo {
        int payloadEnumValue;
        int payloadSubEnumValue;
        int payloadPositionIndex;
        
        PayloadInfo() : payloadEnumValue(52), payloadSubEnumValue(0), payloadPositionIndex(0) {}
    };

    struct MissionConfig {
        FlyToWaylineMode flyToWaylineMode;
        FinishAction finishAction;
        ExitOnRCLost exitOnRCLost;
        int takeOffSecurityHeight;
        int globalTransitionalSpeed;
        DroneInfo droneInfo;
        PayloadInfo payloadInfo;
        
        MissionConfig() : 
            flyToWaylineMode(FlyToWaylineMode::Safely),
            finishAction(FinishAction::GoHome),
            exitOnRCLost(ExitOnRCLost::GoContinue),
            takeOffSecurityHeight(20),
            globalTransitionalSpeed(5),
            droneInfo(),
            payloadInfo() {}
    };

    struct WaylineCoordinateSysParam {
        CoordinateMode coordinateMode;
        HeightMode heightMode;
        PositioningType positioningType;
        int globalHeight;
        
        WaylineCoordinateSysParam() : 
            coordinateMode(CoordinateMode::WGS84),
            heightMode(HeightMode::RelativeToStartPoint),
            positioningType(PositioningType::GPS),
            globalHeight(100) {}
    };

    struct WaypointHeadingParam {
        WaypointHeadingMode waypointHeadingMode;
        bool waypointHeadingAngleEnable;
        int waypointHeadingAngle;
        std::string waypointPoiPoint;
        
        WaypointHeadingParam() : 
            waypointHeadingMode(WaypointHeadingMode::FollowWayline),
            waypointHeadingAngleEnable(false),
            waypointHeadingAngle(0),
            waypointPoiPoint("0.000000,0.000000,0.000000") {}
    };

    // 航点转弯参数
    struct WaypointTurnParam {
        WaypointTurnMode waypointTurnMode;
        int waypointTurnDampingDist;
        
        WaypointTurnParam() : 
            waypointTurnMode(WaypointTurnMode::ToPointAndStopWithDiscontinuityCurvature),
            waypointTurnDampingDist(0) {}
    };

    // 航点结构体
    struct WaypointT {
        double longitude;
        double latitude;
        int ellipsoidHeight_a;
        int height_a;
        int executeHeight_b;
        int waypointSpeed_b;
        bool useGlobalHeight_a;
        bool useGlobalSpeed_a;
        bool useGlobalHeadingParam_a;
        bool useGlobalTurnParam_a;
        bool useStraightLine_b;
        WaypointHeadingParam headingParam_b;
        WaypointTurnParam turnParam_b;
        
		WaypointT() :
            longitude(0.0),
            latitude(0.0),
            ellipsoidHeight_a(100),
            height_a(100),
            executeHeight_b(100),
            waypointSpeed_b(5),
            useGlobalHeight_a(true),
            useGlobalSpeed_a(true),
            useGlobalHeadingParam_a(true),
            useGlobalTurnParam_a(true),
            useStraightLine_b(true),
            headingParam_b(),
            turnParam_b() {}
            
		WaypointT(double lon, double lat) :
            longitude(lon),
            latitude(lat),
            ellipsoidHeight_a(100),
            height_a(100),
            executeHeight_b(100),
            waypointSpeed_b(5),
            useGlobalHeight_a(true),
            useGlobalSpeed_a(true),
            useGlobalHeadingParam_a(true),
            useGlobalTurnParam_a(true),
            useStraightLine_b(true),
            headingParam_b(),
            turnParam_b() {}
    };

    // 航线结构体 (对应Folder)
    struct Wayline {
        // 来自 WaylineTemplate 的字段
        TemplateType templateType_a;
        GimbalPitchMode gimbalPitchMode_a;
        WaypointTurnMode globalWaypointTurnMode;
        HeightMode executeHeightMode_b;
        bool useGlobalTransitionalSpeed_a;
        bool caliFlightEnable_a;
        int templateId;
        int autoFlightSpeed;
        int transitionalSpeed_a;
        int waylineId_b;
        double distance_b;
        double duration_b;
        WaylineCoordinateSysParam coordinateSysParam_a;
        WaypointHeadingParam globalHeadingParam_a;
        std::vector<WaypointT> waypoints;
        
        Wayline() : 
            // WaylineTemplate 部分的初始化
            templateType_a(TemplateType::Waypoint),
            gimbalPitchMode_a(GimbalPitchMode::Manual),
            globalWaypointTurnMode(WaypointTurnMode::ToPointAndStopWithDiscontinuityCurvature),
            executeHeightMode_b(HeightMode::RelativeToStartPoint),
            useGlobalTransitionalSpeed_a(false),
            caliFlightEnable_a(false),
            templateId(0),
            autoFlightSpeed(5),
            transitionalSpeed_a(5),
            waylineId_b(0),
            distance_b(192.275848388672),
            duration_b(35.8362197875977),
            coordinateSysParam_a(),
            globalHeadingParam_a(),
            // Wayline 部分的初始化
            waypoints() {}
    };

    struct Document {
        uint64_t createTime;
        uint64_t updateTime;
        MissionConfig missionConfig;
        Wayline wayline;
        
        Document() {
            // 获取当前时间（毫秒）
            auto now = std::chrono::system_clock::now();
            auto duration = now.time_since_epoch();
            auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration).count();
            
            createTime = millis;
            updateTime = millis;
            missionConfig = MissionConfig();
            wayline = Wayline();
        }
    };

	// 为所有结构体添加序列化操作符
	inline CBuffer &operator << (CBuffer &buffer, const DroneInfo &info) {
		return buffer << info.droneEnumValue << info.droneSubEnumValue;
	}

	inline CBuffer &operator >> (CBuffer &buffer, DroneInfo &info) {
		return buffer >> info.droneEnumValue >> info.droneSubEnumValue;
	}

	inline CBuffer &operator << (CBuffer &buffer, const PayloadInfo &info) {
		return buffer << info.payloadEnumValue << info.payloadSubEnumValue << info.payloadPositionIndex;
	}

	inline CBuffer &operator >> (CBuffer &buffer, PayloadInfo &info) {
		return buffer >> info.payloadEnumValue >> info.payloadSubEnumValue >> info.payloadPositionIndex;
	}

	inline CBuffer &operator << (CBuffer &buffer, const MissionConfig &config) {
		return buffer << (unsigned char)config.flyToWaylineMode
			<< (unsigned char)config.finishAction
			<< (unsigned char)config.exitOnRCLost
			<< config.takeOffSecurityHeight
			<< config.globalTransitionalSpeed
			<< config.droneInfo
			<< config.payloadInfo;
	}

	inline CBuffer &operator >> (CBuffer &buffer, MissionConfig &config) {
		unsigned char flyMode, finishAction, exitAction;
		buffer >> flyMode >> finishAction >> exitAction;
		config.flyToWaylineMode = static_cast<FlyToWaylineMode>(flyMode);
		config.finishAction = static_cast<FinishAction>(finishAction);
		config.exitOnRCLost = static_cast<ExitOnRCLost>(exitAction);
		return buffer >> config.takeOffSecurityHeight
			>> config.globalTransitionalSpeed
			>> config.droneInfo
			>> config.payloadInfo;
	}

	inline CBuffer &operator << (CBuffer &buffer, const WaylineCoordinateSysParam &param) {
		return buffer << (unsigned char)param.coordinateMode
			<< (unsigned char)param.heightMode
			<< (unsigned char)param.positioningType
			<< param.globalHeight;
	}

	inline CBuffer &operator >> (CBuffer &buffer, WaylineCoordinateSysParam &param) {
		unsigned char coordMode, heightMode, posType;
		buffer >> coordMode >> heightMode >> posType;
		param.coordinateMode = static_cast<CoordinateMode>(coordMode);
		param.heightMode = static_cast<HeightMode>(heightMode);
		param.positioningType = static_cast<PositioningType>(posType);
		return buffer >> param.globalHeight;
	}

	inline CBuffer &operator << (CBuffer &buffer, const WaypointHeadingParam &param) {
		return buffer << (unsigned char)param.waypointHeadingMode
			<< param.waypointHeadingAngleEnable
			<< param.waypointHeadingAngle
			<< param.waypointPoiPoint;
	}

	inline CBuffer &operator >> (CBuffer &buffer, WaypointHeadingParam &param) {
		unsigned char headingMode;
		buffer >> headingMode;
		param.waypointHeadingMode = static_cast<WaypointHeadingMode>(headingMode);
		return buffer >> param.waypointHeadingAngleEnable
			>> param.waypointHeadingAngle
			>> param.waypointPoiPoint;
	}

	inline CBuffer &operator << (CBuffer &buffer, const WaypointTurnParam &param) {
		return buffer << (unsigned char)param.waypointTurnMode
			<< param.waypointTurnDampingDist;
	}

	inline CBuffer &operator >> (CBuffer &buffer, WaypointTurnParam &param) {
		unsigned char turnMode;
		buffer >> turnMode;
		param.waypointTurnMode = static_cast<WaypointTurnMode>(turnMode);
		return buffer >> param.waypointTurnDampingDist;
	}

	inline CBuffer &operator << (CBuffer &buffer, const WaypointT &waypoint) {
		return buffer << waypoint.longitude
			<< waypoint.latitude
			<< waypoint.ellipsoidHeight_a
			<< waypoint.height_a
			<< waypoint.executeHeight_b
			<< waypoint.waypointSpeed_b
			<< waypoint.useGlobalHeight_a
			<< waypoint.useGlobalSpeed_a
			<< waypoint.useGlobalHeadingParam_a
			<< waypoint.useGlobalTurnParam_a
			<< waypoint.useStraightLine_b
			<< waypoint.headingParam_b
			<< waypoint.turnParam_b;
	}

	inline CBuffer &operator >> (CBuffer &buffer, WaypointT &waypoint) {
		return buffer >> waypoint.longitude
			>> waypoint.latitude
			>> waypoint.ellipsoidHeight_a
			>> waypoint.height_a
			>> waypoint.executeHeight_b
			>> waypoint.waypointSpeed_b
			>> waypoint.useGlobalHeight_a
			>> waypoint.useGlobalSpeed_a
			>> waypoint.useGlobalHeadingParam_a
			>> waypoint.useGlobalTurnParam_a
			>> waypoint.useStraightLine_b
			>> waypoint.headingParam_b
			>> waypoint.turnParam_b;
	}

	inline CBuffer &operator << (CBuffer &buffer, const Wayline &wayline) {
		return buffer << (unsigned char)wayline.templateType_a
			<< (unsigned char)wayline.gimbalPitchMode_a
			<< (unsigned char)wayline.globalWaypointTurnMode
			<< (unsigned char)wayline.executeHeightMode_b
			<< wayline.useGlobalTransitionalSpeed_a
			<< wayline.caliFlightEnable_a
			<< wayline.templateId
			<< wayline.autoFlightSpeed
			<< wayline.transitionalSpeed_a
			<< wayline.waylineId_b
			<< wayline.distance_b
			<< wayline.duration_b
			<< wayline.coordinateSysParam_a
			<< wayline.globalHeadingParam_a
			<< wayline.waypoints;
	}

	inline CBuffer &operator >> (CBuffer &buffer, Wayline &wayline) {
		unsigned char templateType, gimbalMode, turnMode, heightMode;
		buffer >> templateType >> gimbalMode >> turnMode >> heightMode;
		wayline.templateType_a = static_cast<TemplateType>(templateType);
		wayline.gimbalPitchMode_a = static_cast<GimbalPitchMode>(gimbalMode);
		wayline.globalWaypointTurnMode = static_cast<WaypointTurnMode>(turnMode);
		wayline.executeHeightMode_b = static_cast<HeightMode>(heightMode);
		return buffer >> wayline.useGlobalTransitionalSpeed_a
			>> wayline.caliFlightEnable_a
			>> wayline.templateId
			>> wayline.autoFlightSpeed
			>> wayline.transitionalSpeed_a
			>> wayline.waylineId_b
			>> wayline.distance_b
			>> wayline.duration_b
			>> wayline.coordinateSysParam_a
			>> wayline.globalHeadingParam_a
			>> wayline.waypoints;
	}

	inline CBuffer &operator << (CBuffer &buffer, const Document &doc) {
		return buffer << doc.createTime
			<< doc.updateTime
			<< doc.missionConfig
			<< doc.wayline;
	}

	inline CBuffer &operator >> (CBuffer &buffer, Document &doc) {
		return buffer >> doc.createTime
			>> doc.updateTime
			>> doc.missionConfig
			>> doc.wayline;
	}

	WPML_API std::string toWaylines(const Document &doc);
	WPML_API std::string toTemplate(const Document &doc);
}

#endif